﻿using FitnessDiary.Domain.Abstract;
using FitnessDiary.WebUI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FitnessDiary.Domain.Entities;

namespace FitnessDiary.WebUI.ControllerHelpers
{
	public class DiaryHelper
	{
		public static DiaryModel GetDiaryModel(IFitnessDiaryRepository repository, DateTime actualDay, int week, int userId)
		{
			DateTime firstDay = GetFirstDay(actualDay, week);
			DateTime lastDay = GetLastDay(actualDay, week);
			List<Hit> hits = repository.Hits
				.Where(h => h.Date >= firstDay)
				.Where(h => h.Date <= lastDay)
				.Where(h => h.Stat.UserId == userId)
				.OrderBy(a => a.Date)
				.ToList();
			DiaryModel model = new DiaryModel
			{
				Calendar = CreateCalendar(hits, firstDay),
				Week = week,
				FirstDay = firstDay,
				Today = actualDay
			};
			return model;
		}

		private static DateTime GetFirstDay(DateTime actualDay, int week)
		{
			int dayOfWeek = (int)actualDay.DayOfWeek;
			if (dayOfWeek == 0)
				dayOfWeek = 7;
			return (actualDay.AddDays(week * 7 - 14 - (dayOfWeek - 1)));
		}

		private static DateTime GetLastDay(DateTime actualDay, int week)
		{
			int dayOfWeek = (int)actualDay.DayOfWeek;
			if (dayOfWeek == 0)
				dayOfWeek = 7;
			return (actualDay.AddDays((7 - dayOfWeek) - (week * -7)));
		}

		private static Calendar CreateCalendar(List<Hit> hits, DateTime firstDay)
		{
			Calendar calendar = new Calendar { Weeks = new List<Week>() };
			int numRows = 3;
			int numCols = 7;
			int weekNumber = 1;
			DateTime actualDay = firstDay;
			for (int i = 0; i < numRows; i++)
			{
				Week week = new Week { Days = new List<Day>(), WeekNumber = weekNumber };
				weekNumber++;
				for (int j = 0; j < numCols; j++)
				{
					Day day = new Day() { Hits = new List<Hit>(), Date = actualDay };
					foreach (Hit h in hits)
					{
						if (h.Date == actualDay)
							day.Hits.Add(h);
					}
					week.Days.Add(day);
					actualDay = actualDay.AddDays(1.0);
				}
				calendar.Weeks.Add(week);
			}
			return calendar;
		}

		public static DateTime Today(string timeZoneOffset)
		{
			DateTime utcTime = DateTime.Now.ToUniversalTime();
			DateTime localTime = utcTime.AddMinutes(-Double.Parse(timeZoneOffset));
			return localTime.Date;
		}

		public static DateTime GetUserLocalTime(string timeZoneOffset)
		{
			DateTime utcTime = DateTime.Now.ToUniversalTime();
			DateTime localTime = utcTime.AddMinutes(-Double.Parse(timeZoneOffset));
			return localTime;
		}
	}
}